package com.ls.utils.pay;

import com.ls.entity.Holiday;
import com.ls.entity.SmsRule;
import com.ls.service.IHolidayService;
import com.nlf.calendar.Lunar;
import com.nlf.calendar.Solar;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import static com.ls.constant.SystemConstants.*;
@Slf4j
public class TimeUtils {
    private static SimpleDateFormat sdFormat = null;
    public static String YMD_HMS = "yyyy-MM-dd HH:mm:ss";
    public static String YMD_HM = "yyyy-MM-dd HH:mm";
    public static String YMD = "yyyy-MM-dd";
    public static String YM = "yyyy-MM";
    public static String HM = "HH:mm";

    /**
     * 把服务器的时间转换为本地utc 时间
     *
     * @param time
     * @return
     */
    public static String convert2LocalUTCTime(String time) {
        return convert2LocalUTCTime(time, YMD_HMS);
    }

    public static String convert2LocalUTCTime(String time, String dformat) {
        String localTime = null;
        try {

            if (time == null || time.equals("")) {
                return "";
            }
            SimpleDateFormat format = new SimpleDateFormat(dformat);
            // format.setTimeZone(TimeZone.getTimeZone("UTC"));
            Date gpsUTCDate = null;
            try {
                gpsUTCDate = format.parse(time);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            format.setTimeZone(TimeZone.getDefault());
            localTime = format.format(gpsUTCDate);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return localTime;
    }

    /**
     * 计算年龄
     */
    public static int getAge(String time) {
        int age = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date birthDay;
        try {
            birthDay = sdf.parse(time);

            Calendar cal = Calendar.getInstance();
            if (cal.before(birthDay)) {
                throw new IllegalArgumentException("出生时间大于当前时间!");
            }

            int yearNow = cal.get(Calendar.YEAR);
            int monthNow = cal.get(Calendar.MONTH) + 1;
            int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
            cal.setTime(birthDay);
            int yearBirth = cal.get(Calendar.YEAR);
            int monthBirth = cal.get(Calendar.MONTH);
            int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
            age = yearNow - yearBirth;
            if (monthNow <= monthBirth) {
                if (monthNow == monthBirth) {
                    // monthNow==monthBirth
                    if (dayOfMonthNow <= dayOfMonthBirth) {
                        age--;
                    }
                } else {
                    // monthNow>monthBirth
                    age--;
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return age;
    }

    /**
     * 计算月份
     */
    public static int getMonth(String time) {
        int ageMonth = 0;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date birthDay;
        try {
            birthDay = sdf.parse(time);

            Calendar cal = Calendar.getInstance();
            if (cal.before(birthDay)) {
                throw new IllegalArgumentException("出生时间大于当前时间!");
            }

            int monthNow = cal.get(Calendar.MONTH) + 1;
            int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
            cal.setTime(birthDay);
            int monthBirth = cal.get(Calendar.MONTH);
            int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

            if (monthBirth < monthNow) {
                ageMonth = monthNow - monthBirth;
                if (dayOfMonthBirth <= dayOfMonthNow) {
                    ageMonth--;
                }

            } else {
                ageMonth = 12 - (monthBirth - monthNow);
                if (dayOfMonthBirth <= dayOfMonthNow) {
                    ageMonth--;
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return ageMonth;
    }

    /**
     * <li>功能描述：时间相减得到天数
     */
    public static int reduceDays(String dateStr1, String dateStr2) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
        try {
            dateStr1 = sdf.format(sdf2.parse(dateStr1));
            dateStr2 = sdf.format(sdf2.parse(dateStr2));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int year1 = Integer.parseInt(dateStr1.substring(0, 4));
        int month1 = Integer.parseInt(dateStr1.substring(4, 6));
        int day1 = Integer.parseInt(dateStr1.substring(6, 8));
        int year2 = Integer.parseInt(dateStr2.substring(0, 4));
        int month2 = Integer.parseInt(dateStr2.substring(4, 6));
        int day2 = Integer.parseInt(dateStr2.substring(6, 8));
        Calendar c1 = Calendar.getInstance();
        c1.set(Calendar.YEAR, year1);
        c1.set(Calendar.MONTH, month1 - 1);
        c1.set(Calendar.DAY_OF_MONTH, day1);
        Calendar c2 = Calendar.getInstance();
        c2.set(Calendar.YEAR, year2);
        c2.set(Calendar.MONTH, month2 - 1);
        c2.set(Calendar.DAY_OF_MONTH, day2);
        long mills = c1.getTimeInMillis() > c2.getTimeInMillis() ? c1
                .getTimeInMillis() - c2.getTimeInMillis() : c2
                .getTimeInMillis() - c1.getTimeInMillis();
        return (int) (mills / 1000 / 3600 / 24);
    }

    /**
     * 时期短时间相减，
     *
     * @return 返回相减后的时间戳
     */
    public static long differShort(String start, String end) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        try {
            start = sdf.format(sdf2.parse(start));
            end = sdf.format(sdf2.parse(end));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int year1 = Integer.parseInt(start.substring(0, 4));
        int month1 = Integer.parseInt(start.substring(4, 6));
        int day1 = Integer.parseInt(start.substring(6, 8));
        int hour1 = Integer.parseInt(start.substring(8, 10));
        int minute1 = Integer.parseInt(start.substring(10, 12));

        int year2 = Integer.parseInt(end.substring(0, 4));
        int month2 = Integer.parseInt(end.substring(4, 6));
        int day2 = Integer.parseInt(end.substring(6, 8));
        int hour2 = Integer.parseInt(end.substring(8, 10));
        int minute2 = Integer.parseInt(end.substring(10, 12));

        Calendar c1 = Calendar.getInstance();
        c1.set(Calendar.YEAR, year1);
        c1.set(Calendar.MONTH, month1 - 1);
        c1.set(Calendar.DAY_OF_MONTH, day1);
        c1.set(Calendar.HOUR_OF_DAY, hour1);
        c1.set(Calendar.MINUTE, minute1);

        Calendar c2 = Calendar.getInstance();
        c2.set(Calendar.YEAR, year2);
        c2.set(Calendar.MONTH, month2 - 1);
        c2.set(Calendar.DAY_OF_MONTH, day2);
        c2.set(Calendar.HOUR_OF_DAY, hour2);
        c2.set(Calendar.MINUTE, minute2);

        long mills = c2.getTimeInMillis() - c1.getTimeInMillis();
        return mills;
    }

    /**
     * 把时间格式转换为时间戳
     */
    public static long getTimestamp(String time) {
        SimpleDateFormat format = new SimpleDateFormat(YMD_HMS);
        try {
            Date data = format.parse(time);
            return data.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 把时间格式转换为时间戳
     */
    public static long getTimestamp(String time, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        try {
            Date data = format.parse(time);
            return data.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 时间戳转换为时间格式
     */
    public static String getTimeStringByTimetamp(String time, String pattern) {
        if (time == null || "".equals(time) || "0".equals(time))
            return "";
        if (pattern == null || "".equals(pattern)) {
            pattern = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        long tmp = 0;
        try {
            tmp = Long.parseLong(time);
        } catch (Exception e) {
        }
        if (tmp == 0)
            return "";
        String date = format.format(tmp);
        return date;
    }

    /**
     * 时间戳转换为时间格式
     */
    public static String getTimeStringByTimetamp(String time) {
        if (time == null || "".equals(time) || "0".equals(time))
            return "";
        if (YMD_HMS == null || "".equals(YMD_HMS)) {
            YMD_HMS = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat format = new SimpleDateFormat(YMD_HMS);
        long tmp = 0;
        try {
            tmp = Long.parseLong(time);
        } catch (Exception e) {
        }
        if (tmp == 0)
            return "";
        String date = format.format(tmp);
        return date;
    }

    /**
     * 时间戳转换为时间格式 (long)
     */
    public static String getTimeStringByTimetamp(long time, String pattern) {
        if (pattern == null) {
            pattern = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        String date = format.format(new Date(time));
        return date;
    }

    /**
     * 时间戳转换为时间格式 (long)
     */
    public static String getTimeStringByTimetamp(long time) {
        if (YMD_HMS == null) {
            YMD_HMS = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat format = new SimpleDateFormat(YMD_HMS);
        String date = format.format(new Date(time));
        return date;
    }

    public static String timeFormat(long timeMillis, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.CHINA);
        return format.format(new Date(timeMillis));
    }

    public static String formatPhotoDate(long time) {
        return timeFormat(time, "yyyy-MM-dd");
    }

    /**
     * 得到照片拍摄时间
     */
    public static String formatPhotoDate(String path) {
        File file = new File(path);
        if (file.exists()) {
            long time = file.lastModified();
            return formatPhotoDate(time);
        }
        return "1970-01-01";
    }

    /**
     * 格式化时间，格式为 00:00,单位为毫秒
     */
    public static String formatTime(String time) {
        return formatTime(TxtUtil.getLong(time));
    }

    /**
     * 格式化时间，格式为 00:00,单位为毫秒
     */
    public static String formatTime(long time) {
        if (time < 0)
            return "00:00";

        String res = "";

        int tmp = (int) (time / 1000);
        int hour = tmp / 3600;
        int minute = tmp / 60 % 60;
        int secound = tmp % 60;
        res += (hour > 0 ? (((hour / 10 >= 1) ? hour + "" : ("0" + hour)) + ":") : "")
                + ((minute / 10 >= 1) ? minute + "" : ("0" + minute)) + ":"
                + ((secound / 10 >= 1) ? secound + "" : ("0" + secound)) + "";

        return res;
    }

    /**
     * 单位为毫秒
     */
    public static String getWeek(String time) {
        return getWeek(TxtUtil.getLong(time));
    }

    /**
     * 单位为毫秒
     */
    public static String getWeek(long time) {
        String pattern = "EE";
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        String date = format.format(new Date(time));
        return date;
    }

    public static String getLocalDate(String pattern) {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(pattern));
    }

    public static String getLocalDate() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(YMD_HMS));
    }

    public static Long getLocalDatetamp() {
        return new Date().getTime();
    }

    /**
     * 得到 YMD HMS
     *
     * @param hour x小时前
     */
    public static String getLastHourTime(int hour) {
        return TimeUtils.getTimeStringByTimetamp(getHourStartCalendar(hour).getTimeInMillis());
    }

    /**
     * 得到今天的日期对象，日期定位到今日的0时0分0秒 ,例如2022年2月2日 0时0分0秒
     */
    public static Date getToday() {
        Date date = new Date();
        date.setTime(getDayStartCalendar(0).getTimeInMillis());
        return date;
    }


    /**
     * 得到今天的日期 YMD HMS
     */
    public static String getTodayStartTime() {
        return TimeUtils.getTimeStringByTimetamp(getDayStartCalendar(0).getTimeInMillis());
    }

    /**
     * 得到今天的日期 YMD HMS
     */
    public static String getTodayEndTime() {
        return TimeUtils.getTimeStringByTimetamp(getDayEndCalendar(0).getTimeInMillis());
    }

    /**
     * 得到今天的日期 YMD HMS
     *
     * @param day 0表示今天 1表示明天 -1表示昨天
     */
    public static String getDayStartTime(Integer day) {
        return TimeUtils.getTimeStringByTimetamp(getDayStartCalendar(day).getTimeInMillis());
    }

    /**
     * 得到今天的日期 YMD HMS
     *
     * @param day 0表示今天 1表示明天 -1表示昨天
     */
    public static String getDayEndTime(Integer day) {
        return TimeUtils.getTimeStringByTimetamp(getDayEndCalendar(day).getTimeInMillis());
    }

    /**
     * 得到x小时日期对象
     *
     * @param hour 加减的小时
     */
    public static Calendar getHourStartCalendar(Integer hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        return calendar;
    }

    /**
     * 得到今天的日期对象
     *
     * @param day 加减的天数0表示今天 1表示明天 -1表示昨天
     */
    public static Calendar getDayStartCalendar(Integer day) {
        Calendar calendar = Calendar.getInstance();
        if (day != null && day > 0) {
            calendar.add(Calendar.DAY_OF_MONTH, day);
        }
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        return calendar;
    }

    /**
     * 得到今天的日期对象
     *
     * @param day 加减的天数
     */
    public static Calendar getDayEndCalendar(Integer day) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, day);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);

        return calendar;
    }

    /**
     * 得到昨天的日期对象，日期定位到今日的0时0分0秒 ,例如2022年2月2日 0时0分0秒
     */
    public static Date getYesterday() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        date.setTime(calendar.getTimeInMillis());
        return date;
    }

    /**
     * 得到明天的日期对象，日期定位到今日的0时0分0秒 ,例如2022年2月2日 0时0分0秒
     */
    public static Date getTomorrow() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        date.setTime(calendar.getTimeInMillis());
        return date;
    }


    public static Long getLocalDatestamp() {
        return new Date().getTime();
    }


    /**
     * 返回阳历发送日期
     */
    public static LocalDate getYangSolarDate(LocalDate date, int day, int type,int period) {
        //type : 0表示农历 1表示阳历
        //date代表输入的日期
        //day代表提前的日期
        //period  1为按年重复，2为按月重复，3为按周重复，4为按天重复，0为不重复 ,如果period为0则不更新年份，其他则年份为今年
        LocalDate date1;
        if (type == NUMBER_0) {
            if (period!=0){
                // 将农历日期转换成今年的阳历
                int year = LocalDate.now().getYear();
                Lunar lunar = new Lunar(year, date.getMonthValue(), date.getDayOfMonth());
                Solar solar = lunar.getSolar();
                date1 = LocalDate.parse(solar.toYmd(), DateTimeFormatter.ISO_LOCAL_DATE);
            }else{
                //将农历转成阳历
                Lunar lunar = new Lunar(date.getYear(), date.getMonthValue(), date.getDayOfMonth());
                Solar solar = lunar.getSolar();
                date1 = LocalDate.parse(solar.toYmd(), DateTimeFormatter.ISO_LOCAL_DATE);
            }
            date1 = date1.minusDays(day);
        } else {
            if (period!=0){
                date1 = convertToThisYear(date);
            }else{
                date1 = date;
            }
            // 调整日期（减去指定的天数）
            date1 = date1.minusDays(day);
        }
        return date1;
    }
    /**
     * 获取下次执行日期
     */
    public static LocalDate getNextExecuteDate(Integer advance,Holiday holiday,LocalDate now) {
        if (holiday.getHolidaySort() == NUMBER_0) {
            //不重复
            if (holiday.getPeriod() == NUMBER_0) {
                LocalDate date = getYangSolarDate(holiday.getStartTime(), advance, holiday.getHolidayType(),holiday.getPeriod());
                return date;
                //按年和按月重复
            } else if (holiday.getPeriod() == NUMBER_1 || holiday.getPeriod() == NUMBER_2) {
                LocalDate nextDate = holiday.getStartTime();
                while (getYangSolarDate(nextDate, advance, holiday.getHolidayType(),0).isBefore(now)) {
                    nextDate = calculateNextDate(nextDate, holiday.getPeriod(), holiday.getPeriodCount(), holiday.getHolidayType());
                }
                return getYangSolarDate(nextDate, advance, holiday.getHolidayType(),0);
            } else {
                //按天重复
                LocalDate startDate = holiday.getStartTime().minusDays(advance);
                LocalDate nextDate = getYangSolarDate(startDate, 0,holiday.getHolidayType(),0);
                while ((nextDate.minusDays(advance)).isBefore(now)) {
                    nextDate = calculateNextDate(nextDate, holiday.getPeriod(), holiday.getPeriodCount(), holiday.getHolidayType());
                }
                return nextDate.minusDays(advance);
            }
        }
        return null;
    }
    public static LocalDate calculateNextDate(LocalDate baseDate, int period, int periodCount, int type) {
        if (period == 1) {
            baseDate = baseDate.plusYears(periodCount);
        } else if (period == 2) {
            baseDate = baseDate.plusMonths(periodCount);
        } else if (period == 3) {
            baseDate = baseDate.plusWeeks(periodCount);
        } else if (period == 4) {
            baseDate = baseDate.plusDays(periodCount);
        }
        return baseDate;
    }
    /**
     * 将一个日期的年份转成今年
     */
    public static LocalDate convertToThisYear(LocalDate date) {
        return LocalDate.of(LocalDate.now().getYear(), date.getMonth(), date.getDayOfMonth());
    }
    /**
     * 日期转换为农历
     */
    public static String convertToLunar(LocalDate date, Integer type) {
        // 直接使用农历年、月、日创建对象（假设date参数本身就是农历日期）
        Lunar lunar = new Lunar(date.getYear(), date.getMonthValue(), date.getDayOfMonth());

        // 处理闰月情况（例如：闰七月会返回"闰七月"）
        String month = lunar.getMonthInChinese();
        // 获取农历日（自动包含"廿"等中文表示）
        String day = lunar.getDayInChinese();
        String result;
        if (type == 1) {
            result = month + "月" + day;
        } else {
            result = lunar.getYearInChinese() + "年" + month + "月" + day;
        }
        return result;
    }
    /**
     * 公历日期转农历（支持闰月显示）
     * @param solarDate 公历日期
     * @param type 0-不显示年份，1-显示完整年份
     */
    public static String convertToLunar2(LocalDate solarDate, Integer type) {
        Solar solar = new Solar(solarDate.getYear(), solarDate.getMonthValue(), solarDate.getDayOfMonth());
        Lunar lunar = solar.getLunar();

        String month = lunar.getMonthInChinese();
        String day = lunar.getDayInChinese();

        String result;
        if (type == 1) {
            result = month + "月" + day;
        } else {
            result = lunar.getYearInChinese() + "年" + month + "月" + day;
        }
        return result;
    }
}
